/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2021 3snic Technologies Co., Ltd */

#ifndef SSSNIC_CFG_H
#define SSSNIC_CFG_H
#include <linux/types.h>

#include "ssshw_mgmt_msg_base.h"
#include "sssnic_comm.h"
#include "sssnic_mt.h"
#include "sssnic_common.h"
#include "sssnic_nicq.h"
#ifndef __UEFI__
#include "sssnic_lld.h"
#endif

#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)

#define SSSNIC_VLAN_PRIORITY_SHIFT 13

#define SSSNIC_RSS_INDIR_4B_UNIT 3
#define SSSNIC_RSS_INDIR_NUM 2

#define SSSNIC_RSS_KEY_RSV_NUM 2
#define SSSNIC_MAX_NUM_RQ 256

#define SSSNIC_MIN_MTU_SIZE 256
#define SSSNIC_MAX_JUMBO_FRAME_SIZE 9600

#define SSSNIC_PF_SET_VF_ALREADY 0x4
#define SSSNIC_MGMT_STATUS_EXIST 0x6
#define CHECK_IPSU_15BIT 0x8000

#define SSSNIC_MGMT_STATUS_TABLE_EMPTY 0xB /* Table empty */
#define SSSNIC_MGMT_STATUS_TABLE_FULL 0xC  /* Table full */

#define SSSNIC_LOWEST_LATENCY 1
#define SSSNIC_MULTI_VM_LATENCY 32
#define SSSNIC_MULTI_VM_PENDING_LIMIT 4

#define SSSNIC_RX_RATE_LOW 200000
#define SSSNIC_RX_COAL_TIME_LOW 25
#define SSSNIC_RX_PENDING_LIMIT_LOW 2

#define SSSNIC_RX_RATE_HIGH 700000
#define SSSNIC_RX_COAL_TIME_HIGH 225
#define SSSNIC_RX_PENDING_LIMIT_HIGH 8

#define SSSNIC_RX_RATE_THRESH 50000
#define SSSNIC_TX_RATE_THRESH 50000
#define SSSNIC_RX_RATE_LOW_VM 100000
#define SSSNIC_RX_PENDING_LIMIT_HIGH_VM 87

#define SSSNIC_DCB_PCP 0
#define SSSNIC_DCB_DSCP 1

#define MAX_LIMIT_BW 100

enum sssnic_valid_link_settings {
	SSSLINK_SET_SPEED = 0x1,
	SSSLINK_SET_AUTONEG = 0x2,
	SSSLINK_SET_FEC = 0x4,
};

enum sssnic_link_follow_status {
	SSSNIC_LINK_FOLLOW_DEFAULT,
	SSSNIC_LINK_FOLLOW_PORT,
	SSSNIC_LINK_FOLLOW_SEPARATE,
	SSSNIC_LINK_FOLLOW_STATUS_MAX,
};

struct sssnic_link_ksettings {
	u32 valid_bitmap;
	u8 speed;   /* enum nic_speed_level */
	u8 autoneg; /* 0 - off; 1 - on */
	u8 fec;	    /* 0 - RSFEC; 1 - BASEFEC; 2 - NOFEC */
};

u64 sssnic_get_feature_cap(void *hwdev);

#define SSSNIC_SUPPORT_FEATURE(hwdev, feature) \
	(sssnic_get_feature_cap(hwdev) & NIC_F_##feature)
#define SSSNIC_SUPPORT_CSUM(hwdev) SSSNIC_SUPPORT_FEATURE(hwdev, CSUM)
#define SSSNIC_SUPPORT_SCTP_CRC(hwdev) SSSNIC_SUPPORT_FEATURE(hwdev, SCTP_CRC)
#define SSSNIC_SUPPORT_TSO(hwdev) SSSNIC_SUPPORT_FEATURE(hwdev, TSO)
#define SSSNIC_SUPPORT_UFO(hwdev) SSSNIC_SUPPORT_FEATURE(hwdev, UFO)
#define SSSNIC_SUPPORT_LRO(hwdev) SSSNIC_SUPPORT_FEATURE(hwdev, LRO)
#define SSSNIC_SUPPORT_RSS(hwdev) SSSNIC_SUPPORT_FEATURE(hwdev, RSS)
#define SSSNIC_SUPPORT_RXVLAN_FILTER(hwdev) \
	SSSNIC_SUPPORT_FEATURE(hwdev, RX_VLAN_FILTER)
#define SSSNIC_SUPPORT_VLAN_OFFLOAD(hwdev) \
	(SSSNIC_SUPPORT_FEATURE(hwdev, RX_VLAN_STRIP) && \
	 SSSNIC_SUPPORT_FEATURE(hwdev, TX_VLAN_INSERT))
#define SSSNIC_SUPPORT_VXLAN_OFFLOAD(hwdev) \
	SSSNIC_SUPPORT_FEATURE(hwdev, VXLAN_OFFLOAD)
#define SSSNIC_SUPPORT_IPSEC_OFFLOAD(hwdev) \
	SSSNIC_SUPPORT_FEATURE(hwdev, IPSEC_OFFLOAD)
#define SSSNIC_SUPPORT_FDIR(hwdev) SSSNIC_SUPPORT_FEATURE(hwdev, FDIR)
#define SSSNIC_SUPPORT_PROMISC(hwdev) SSSNIC_SUPPORT_FEATURE(hwdev, PROMISC)
#define SSSNIC_SUPPORT_ALLMULTI(hwdev) SSSNIC_SUPPORT_FEATURE(hwdev, ALLMULTI)
#define SSSNIC_SUPPORT_VF_MAC(hwdev) SSSNIC_SUPPORT_FEATURE(hwdev, VF_MAC)
#define SSSNIC_SUPPORT_RATE_LIMIT(hwdev) SSSNIC_SUPPORT_FEATURE(hwdev, RATE_LIMIT)

enum sssnic_queue_type {
	SSSNIC_SQ,
	SSSNIC_RQ,
	SSSNIC_MAX_QUEUE_TYPE
};

#ifndef __UEFI__
struct ssshw_lld_dev *sssnic_get_lld_dev_by_netdev(struct net_device *netdev);
struct net_device *sssnic_get_netdev_by_lld(struct ssshw_lld_dev *lld_dev);
#endif

struct sssnic_event_link_info {
	u8 valid;
	u8 port_type;
	u8 autoneg_cap;
	u8 autoneg_state;
	u8 duplex;
	u8 speed;
};

enum link_err_type {
	LINK_ERR_MODULE_UNRECOGENIZED,
	LINK_ERR_NUM,
};

enum port_module_event_type {
	SSSNIC_PORT_MODULE_CABLE_PLUGGED,
	SSSNIC_PORT_MODULE_CABLE_UNPLUGGED,
	SSSNIC_PORT_MODULE_LINK_ERR,
	SSSNIC_PORT_MODULE_MAX_EVENT,
};

struct sssnic_port_module_event {
	enum port_module_event_type type;
	enum link_err_type err_type;
};

struct sssnic_dcb_info {
	u8 dcb_on;
	u8 default_cos;
	u8 up_cos[SSSNIC_DCB_COS_MAX];
};

enum sssnic_nic_event_type {
	EVENT_NIC_LINK_DOWN,
	EVENT_NIC_LINK_UP,
	EVENT_NIC_PORT_MODULE_EVENT,
	EVENT_NIC_DCB_STATE_CHANGE,
};

/* serdes/mag消息命令字定义 */
enum mag_cmd {
    /* serdes命令字，统一封装所有serdes命令 */
    SERDES_CMD_PROCESS = 0,

    /* mag命令字，按功能划分 */
    /* 端口配置相关 0-29 */
    MAG_CMD_SET_PORT_CFG = 1,
    MAG_CMD_SET_PORT_ADAPT = 2,
    MAG_CMD_CFG_LOOPBACK_MODE = 3,

    MAG_CMD_GET_PORT_ENABLE = 5,
    MAG_CMD_SET_PORT_ENABLE = 6,
    MAG_CMD_GET_LINK_STATUS = 7,
    MAG_CMD_SET_LINK_FOLLOW = 8,
    MAG_CMD_SET_PMA_ENABLE = 9,
    MAG_CMD_CFG_FEC_MODE = 10,

    MAG_CMD_CFG_AN_TYPE = 12, /* reserved for future use */
    MAG_CMD_CFG_LINK_TIME = 13,

    MAG_CMD_SET_PANGEA_ADAPT = 15,

    /* bios link配置相关 30-49 */
    MAG_CMD_CFG_BIOS_LINK_CFG = 31,
    MAG_CMD_RESTORE_LINK_CFG = 32,
    MAG_CMD_ACTIVATE_BIOS_LINK_CFG = 33,

    /* 光模块、LED、PHY等外设配置管理 50-99 */
    /* LED */
    MAG_CMD_SET_LED_CFG = 50,

    /* PHY */
    MAG_CMD_GET_PHY_INIT_STATUS = 55, /* reserved for future use */

    /* 光模块 */
    MAG_CMD_GET_XSFP_INFO = 60,
    MAG_CMD_SET_XSFP_ENABLE = 61,
    MAG_CMD_GET_XSFP_PRESENT = 62,
    MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, for equipment test */
    MAG_CMD_CFG_XSFP_TEMPERATURE = 64,

    /* 事件上报 100-149 */
    MAG_CMD_WIRE_EVENT = 100,
    MAG_CMD_LINK_ERR_EVENT = 101,

    /* DFX、Counter相关 */
    MAG_CMD_EVENT_PORT_INFO = 150,
    MAG_CMD_GET_PORT_STAT = 151,
    MAG_CMD_CLR_PORT_STAT = 152,
    MAG_CMD_GET_PORT_INFO = 153,
    MAG_CMD_GET_PCS_ERR_CNT = 154,
    MAG_CMD_GET_MAG_CNT = 155,
    MAG_CMD_DUMP_ANTRAIN_INFO = 156,

    MAG_CMD_MAX = 0xFF
};

/* serdes cmd struct define */
#define CMD_ARRAY_BUF_SIZE 64
#define SERDES_CMD_DATA_BUF_SIZE 512
struct serdes_in_info {
    u32 chip_id : 16;
    u32 macro_id : 16;
    u32 start_sds_id : 16;
    u32 sds_num : 16;

    u32 cmd_type : 8; /* reserved for iotype */
    u32 sub_cmd : 8;
    u32 rw : 1; /* 0: read, 1: write */
    u32 rsvd : 15;

    u32 val;
    union {
        char field[CMD_ARRAY_BUF_SIZE];
        u32 addr;
        u8 *ex_param;
    };
};

struct serdes_out_info {
    u32 str_len; /* out_str lenth */
    u32 result_offset;
    u32 type; /* 0:data; 1:string */
    char out_str[SERDES_CMD_DATA_BUF_SIZE];
};

struct serdes_cmd_in {
    struct ssshw_mgmt_msg_head head;

    struct serdes_in_info serdes_in;
};

struct serdes_cmd_out {
    struct ssshw_mgmt_msg_head head;

    struct serdes_out_info serdes_out;
};

enum mag_cmd_port_speed {
    PORT_SPEED_NOT_SET = 0,
    PORT_SPEED_10MB = 1,
    PORT_SPEED_100MB = 2,
    PORT_SPEED_1GB = 3,
    PORT_SPEED_10GB = 4,
    PORT_SPEED_25GB = 5,
    PORT_SPEED_40GB = 6,
    PORT_SPEED_50GB = 7,
    PORT_SPEED_100GB = 8,
    PORT_SPEED_200GB = 9,
    PORT_SPEED_UNKNOWN
};

enum mag_cmd_port_an {
    PORT_AN_NOT_SET = 0,
    PORT_CFG_AN_ON = 1,
    PORT_CFG_AN_OFF = 2
};

enum mag_cmd_port_adapt {
    PORT_ADAPT_NOT_SET = 0,
    PORT_CFG_ADAPT_ON = 1,
    PORT_CFG_ADAPT_OFF = 2
};

enum mag_cmd_port_sriov {
    PORT_SRIOV_NOT_SET = 0,
    PORT_CFG_SRIOV_ON = 1,
    PORT_CFG_SRIOV_OFF = 2
};

enum mag_cmd_port_fec {
    PORT_FEC_NOT_SET = 0,
    PORT_FEC_RSFEC = 1,
    PORT_FEC_BASEFEC = 2,
    PORT_FEC_NOFEC = 3,
    PORT_FEC_LLRSFEC = 4,
    PORT_FEC_AUTO = 5
};

enum mag_cmd_port_lanes {
    PORT_LANES_NOT_SET = 0,
    PORT_LANES_X1 = 1,
    PORT_LANES_X2 = 2,
    PORT_LANES_X4 = 4,
    PORT_LANES_X8 = 8 /* reseverd for future use */
};

enum mag_cmd_port_duplex {
    PORT_DUPLEX_HALF = 0,
    PORT_DUPLEX_FULL = 1
};

enum mag_cmd_wire_node {
    WIRE_NODE_UNDEF = 0,
    CABLE_10G = 1,
    FIBER_10G = 2,
    CABLE_25G = 3,
    FIBER_25G = 4,
    CABLE_40G = 5,
    FIBER_40G = 6,
    CABLE_50G = 7,
    FIBER_50G = 8,
    CABLE_100G = 9,
    FIBER_100G = 10,
    CABLE_200G = 11,
    FIBER_200G = 12,
    WIRE_NODE_NUM
};

/* mag_cmd_set_port_cfg config bitmap */
#define MAG_CMD_SET_SPEED 0x1
#define MAG_CMD_SET_AUTONEG 0x2
#define MAG_CMD_SET_FEC 0x4
#define MAG_CMD_SET_LANES 0x8
struct mag_cmd_set_port_cfg {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 rsvd0[3];

    u32 config_bitmap;
    u8 speed;
    u8 autoneg;
    u8 fec;
    u8 lanes;
    u8 rsvd1[20];
};

/* mag supported/advertised link mode bitmap */
enum mag_cmd_link_mode {
    LINK_MODE_GE = 0,
    LINK_MODE_10GE_BASE_R = 1,
    LINK_MODE_25GE_BASE_R = 2,
    LINK_MODE_40GE_BASE_R4 = 3,
    LINK_MODE_50GE_BASE_R = 4,
    LINK_MODE_50GE_BASE_R2 = 5,
    LINK_MODE_100GE_BASE_R = 6,
    LINK_MODE_100GE_BASE_R2 = 7,
    LINK_MODE_100GE_BASE_R4 = 8,
    LINK_MODE_200GE_BASE_R2 = 9,
    LINK_MODE_200GE_BASE_R4 = 10,
    LINK_MODE_MAX_NUMBERS,

    LINK_MODE_UNKNOWN = 0xFFFF
};

#define LINK_MODE_GE_BIT 0x1u
#define LINK_MODE_10GE_BASE_R_BIT 0x2u
#define LINK_MODE_25GE_BASE_R_BIT 0x4u
#define LINK_MODE_40GE_BASE_R4_BIT 0x8u
#define LINK_MODE_50GE_BASE_R_BIT 0x10u
#define LINK_MODE_50GE_BASE_R2_BIT 0x20u
#define LINK_MODE_100GE_BASE_R_BIT 0x40u
#define LINK_MODE_100GE_BASE_R2_BIT 0x80u
#define LINK_MODE_100GE_BASE_R4_BIT 0x100u
#define LINK_MODE_200GE_BASE_R2_BIT 0x200u
#define LINK_MODE_200GE_BASE_R4_BIT 0x400u

#define CABLE_10GE_BASE_R_BIT LINK_MODE_10GE_BASE_R_BIT
#define CABLE_25GE_BASE_R_BIT (LINK_MODE_25GE_BASE_R_BIT | LINK_MODE_10GE_BASE_R_BIT)
#define CABLE_40GE_BASE_R4_BIT LINK_MODE_40GE_BASE_R4_BIT
#define CABLE_50GE_BASE_R_BIT \
    (LINK_MODE_50GE_BASE_R_BIT | LINK_MODE_25GE_BASE_R_BIT | LINK_MODE_10GE_BASE_R_BIT)
#define CABLE_50GE_BASE_R2_BIT LINK_MODE_50GE_BASE_R2_BIT
#define CABLE_100GE_BASE_R2_BIT (LINK_MODE_100GE_BASE_R2_BIT | LINK_MODE_50GE_BASE_R2_BIT)
#define CABLE_100GE_BASE_R4_BIT (LINK_MODE_100GE_BASE_R4_BIT | LINK_MODE_40GE_BASE_R4_BIT)
#define CABLE_200GE_BASE_R4_BIT \
    (LINK_MODE_200GE_BASE_R4_BIT | LINK_MODE_100GE_BASE_R4_BIT | LINK_MODE_40GE_BASE_R4_BIT)

struct mag_cmd_get_port_info {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 rsvd0[3];

    u8 wire_type;
    u8 an_support;
    u8 an_en;
    u8 duplex;

    u8 speed;
    u8 fec;
    u8 lanes;
    u8 rsvd1;

    u32 supported_mode;
    u32 advertised_mode;
    u8 rsvd2[8];
};

#define MAG_CMD_OPCODE_GET 0
#define MAG_CMD_OPCODE_SET 1
struct mag_cmd_set_port_adapt {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 opcode; /* 0:get adapt info  1:set adapt */
    u8 enable;
    u8 rsvd0;
    u32 speed_mode;
    u32 rsvd1[3];
};

#define MAG_CMD_LP_MODE_SDS_S_TX2RX 1
#define MAG_CMD_LP_MODE_SDS_P_RX2TX 2
#define MAG_CMD_LP_MODE_SDS_P_TX2RX 3
#define MAG_CMD_LP_MODE_MAC_RX2TX 4
#define MAG_CMD_LP_MODE_MAC_TX2RX 5
#define MAG_CMD_LP_MODE_TXDP2RXDP 6
struct mag_cmd_cfg_loopback_mode {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 opcode; /* 0:get loopback mode  1:set loopback mode */
    u8 lp_mode;
    u8 lp_en; /* 0:disable  1:enable */

    u32 rsvd0[2];
};

#define MAG_CMD_PORT_DISABLE 0x0
#define MAG_CMD_TX_ENABLE 0x1
#define MAG_CMD_RX_ENABLE 0x2
/* the physical port is disable only when all pf of the port are set to down, if any pf is enable, the port is enable */
struct mag_cmd_set_port_enable {
    struct ssshw_mgmt_msg_head head;

    u16 function_id; /* function_id should not more than the max support pf_id(32) */
    u16 rsvd0;

    u8 state; /* bitmap bit0:tx_en bit1:rx_en */
    u8 rsvd1[3];
};

struct mag_cmd_get_port_enable {
    struct ssshw_mgmt_msg_head head;

    u8 port;
    u8 state; /* bitmap bit0:tx_en bit1:rx_en */
    u8 rsvd0[2];
};

#define PMA_FOLLOW_DEFAULT 0x0
#define PMA_FOLLOW_ENABLE 0x1
#define PMA_FOLLOW_DISABLE 0x2
#define PMA_FOLLOW_GET 0x4
/* the physical port disable link follow only when all pf of the port are set to follow disable */
struct mag_cmd_set_link_follow {
    struct ssshw_mgmt_msg_head head;

    u16 function_id; /* function_id should not more than the max support pf_id(32) */
    u16 rsvd0;

    u8 follow;
    u8 rsvd1[3];
};

/* firmware also use this cmd report link event to driver */
struct mag_cmd_get_link_status {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 status; /* 0:link down  1:link up */
    u8 rsvd0[2];
};

struct mag_cmd_set_pma_enable {
    struct ssshw_mgmt_msg_head head;

    u16 function_id; /* function_id should not more than the max support pf_id(32) */
    u16 enable;
};

struct mag_cmd_cfg_an_type {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 opcode; /* 0:get an type  1:set an type */
    u8 rsvd0[2];

    u32 an_type; /* 0:ieee   1:25G/50 eth consortium */
};

struct mag_cmd_get_link_time {
    struct ssshw_mgmt_msg_head head;
    u8 port_id;
    u8 rsvd0[3];

    u32 link_up_begin;
    u32 link_up_end;
    u32 link_down_begin;
    u32 link_down_end;
};

struct mag_cmd_cfg_fec_mode {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 opcode; /* 0:get fec mode  1:set fec mode */
    u8 fec;
    u8 rsvd0;
};

/* speed */
#define PANGEA_ADAPT_10G_BITMAP     0xd
#define PANGEA_ADAPT_25G_BITMAP     0x72
#define PANGEA_ADAPT_40G_BITMAP     0x680
#define PANGEA_ADAPT_100G_BITMAP    0x1900

/* speed and fec */
#define PANGEA_10G_NO_BITMAP        0x8
#define PANGEA_10G_BASE_BITMAP      0x4
#define PANGEA_25G_NO_BITMAP        0x10
#define PANGEA_25G_BASE_BITMAP      0x20
#define PANGEA_25G_RS_BITMAP        0x40
#define PANGEA_40G_NO_BITMAP        0x400
#define PANGEA_40G_BASE_BITMAP      0x200
#define PANGEA_100G_NO_BITMAP       0x800
#define PANGEA_100G_RS_BITMAP       0x1000

/* adapt or fec */
#define PANGEA_ADAPT_ADAPT_BITMAP   0x183
#define PANGEA_ADAPT_NO_BITMAP      0xc18
#define PANGEA_ADAPT_BASE_BITMAP    0x224
#define PANGEA_ADAPT_RS_BITMAP      0x1040

/* default cfg */
#define PANGEA_ADAPT_CFG_10G_CR     0x200d
#define PANGEA_ADAPT_CFG_10G_SRLR   0xd
#define PANGEA_ADAPT_CFG_25G_CR     0x207f
#define PANGEA_ADAPT_CFG_25G_SRLR   0x72
#define PANGEA_ADAPT_CFG_40G_CR4    0x2680
#define PANGEA_ADAPT_CFG_40G_SRLR4  0x680
#define PANGEA_ADAPT_CFG_100G_CR4   0x3f80
#define PANGEA_ADAPT_CFG_100G_SRLR4 0x1900
typedef union {
    struct {
        u32 adapt_10g : 1;  /* [0]   adapt_10g  */
        u32 adapt_25g : 1;  /* [1]   adapt_25g  */
        u32 base_10g : 1;   /* [2]   base_10g   */
        u32 no_10g : 1;     /* [3]   no_10g     */
        u32 no_25g : 1;     /* [4]   no_25g     */
        u32 base_25g : 1;   /* [5]   base_25g   */
        u32 rs_25g : 1;     /* [6]   rs_25g     */
        u32 adapt_40g : 1;  /* [7]   adapt_40g  */
        u32 adapt_100g : 1; /* [8]   adapt_100g */
        u32 base_40g : 1;   /* [9]   base_40g   */
        u32 no_40g : 1;     /* [10]  no_40g     */
        u32 no_100g : 1;    /* [11]  no_100g    */
        u32 rs_100g : 1;    /* [12]  rs_100g    */
        u32 auto_neg : 1;   /* [13]  auto_neg   */
        u32 rsvd0 : 18;     /* [31:14] reserved */
    } bits;

    u32 value;
} pangea_adapt_bitmap_u;

#define PANGEA_ADAPT_GET 0x0
#define PANGEA_ADAPT_SET 0x1
struct mag_cmd_set_pangea_adapt {
    struct ssshw_mgmt_msg_head head;

    u16 port_id;
    u8 opcode; /* 0:get adapt info  1:cfg adapt info */
    u8 wire_type;

    pangea_adapt_bitmap_u cfg_bitmap;
    pangea_adapt_bitmap_u cur_bitmap;
    u32 rsvd1[3];
};

struct mag_cmd_cfg_bios_link_cfg {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 opcode; /* 0:get bios link info  1:set bios link cfg */
    u8 clear;
    u8 rsvd0;

    u32 wire_type;
    u8 an_en;
    u8 speed;
    u8 fec;
    u8 rsvd1;
    u32 speed_mode;
    u32 rsvd2[3];
};

struct mag_cmd_restore_link_cfg {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 rsvd[7];
};

struct mag_cmd_activate_bios_link_cfg {
    struct ssshw_mgmt_msg_head head;

    u32 rsvd[8];
};

/* led type */
enum mag_led_type {
    MAG_CMD_LED_TYPE_ALARM = 0x0,
    MAG_CMD_LED_TYPE_LOW_SPEED = 0x1,
    MAG_CMD_LED_TYPE_HIGH_SPEED = 0x2
};

/* led mode */
enum mag_led_mode {
    MAG_CMD_LED_MODE_DEFAULT = 0x0,
    MAG_CMD_LED_MODE_FORCE_ON = 0x1,
    MAG_CMD_LED_MODE_FORCE_OFF = 0x2,
    MAG_CMD_LED_MODE_FORCE_BLINK_1HZ = 0x3,
    MAG_CMD_LED_MODE_FORCE_BLINK_2HZ = 0x4,
    MAG_CMD_LED_MODE_FORCE_BLINK_4HZ = 0x5,
    MAG_CMD_LED_MODE_1HZ = 0x6,
    MAG_CMD_LED_MODE_2HZ = 0x7,
    MAG_CMD_LED_MODE_4HZ = 0x8
};

/* the led is report alarm  when any pf of the port is alram */
struct mag_cmd_set_led_cfg {
    struct ssshw_mgmt_msg_head head;

    u16 function_id;
    u8 type;
    u8 mode;
};

#define XSFP_INFO_MAX_SIZE 640
/* xsfp wire type, refer to cmis protocol definition */
enum mag_wire_type {
    MAG_CMD_WIRE_TYPE_UNKNOWN = 0x0,
    MAG_CMD_WIRE_TYPE_MM = 0x1,
    MAG_CMD_WIRE_TYPE_SM = 0x2,
    MAG_CMD_WIRE_TYPE_COPPER = 0x3,
    MAG_CMD_WIRE_TYPE_ACC = 0x4,
    MAG_CMD_WIRE_TYPE_BASET = 0x5,
    MAG_CMD_WIRE_TYPE_AOC = 0x40,
    MAG_CMD_WIRE_TYPE_ELECTRIC = 0x41,
    MAG_CMD_WIRE_TYPE_BACKPLANE = 0x42
};

struct mag_cmd_get_xsfp_info {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 wire_type;
    u16 out_len;
    u32 rsvd;
    u8 sfp_info[XSFP_INFO_MAX_SIZE];
};

#define MAG_CMD_XSFP_DISABLE 0x0
#define MAG_CMD_XSFP_ENABLE 0x1
/* the sfp is disable only when all pf of the port are set sfp down, if any pf is enable, the sfp is enable */
struct mag_cmd_set_xsfp_enable {
    struct ssshw_mgmt_msg_head head;

    u32 port_id;
    u32 status; /* 0:on 1:off */
};

#define MAG_CMD_XSFP_PRESENT 0x0
#define MAG_CMD_XSFP_ABSENT 0x1
struct mag_cmd_get_xsfp_present {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 abs_status; /* 0:present, 1:absent */
    u8 rsvd[2];
};

#define MAG_CMD_XSFP_READ 0x0
#define MAG_CMD_XSFP_WRITE 0x1
struct mag_cmd_set_xsfp_rw {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 operation; /* 0: read; 1: write */
    u8 value;
    u8 rsvd0;
    u32 devaddr;
    u32 offset;
    u32 rsvd1;
};

struct mag_cmd_cfg_xsfp_temperature {
    struct ssshw_mgmt_msg_head head;

    u8 opcode; /* 0:read  1:write */
    u8 rsvd0[3];
    s32 max_temp;
    s32 min_temp;
};

struct mag_cmd_get_xsfp_temperature {
    struct ssshw_mgmt_msg_head head;

    s16 sfp_temp[8];
    u8 rsvd[32];
    s32 max_temp;
    s32 min_temp;
};

/* xsfp plug event */
struct mag_cmd_wire_event {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 status; /* 0:present, 1:absent */
    u8 rsvd[2];
};

/* link err type definition */
#define MAG_CMD_ERR_XSFP_UNKNOWN 0x0
struct mag_cmd_link_err_event {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 link_err_type;
    u8 rsvd[2];
};

#define MAG_PARAM_TYPE_DEFAULT_CFG 0x0
#define MAG_PARAM_TYPE_BIOS_CFG 0x1
#define MAG_PARAM_TYPE_TOOL_CFG 0x2
#define MAG_PARAM_TYPE_FINAL_CFG 0x3
#define MAG_PARAM_TYPE_WIRE_INFO 0x4
#define MAG_PARAM_TYPE_ADAPT_INFO 0x5
#define MAG_PARAM_TYPE_MAX_CNT 0x6
struct param_head {
    u8 valid_len;
    u8 info_type;
    u8 rsvd[2];
};

struct mag_port_link_param {
    struct param_head head;

    u8 an;
    u8 fec;
    u8 speed;
    u8 rsvd0;

    u32 used;
    u32 an_fec_ability;
    u32 an_speed_ability;
    u32 an_pause_ability;
};

struct mag_port_wire_info {
    struct param_head head;

    u8 status;
    u8 rsvd0[3];

    u8 wire_type;
    u8 default_fec;
    u8 speed;
    u8 rsvd1;
    u32 speed_ability;
};

struct mag_port_adapt_info {
    struct param_head head;

    u32 adapt_en;
    u32 flash_adapt;
    u32 rsvd0[2];

    u32 wire_node;
    u32 an_en;
    u32 speed;
    u32 fec;
};

struct mag_port_param_info {
    u8 parameter_cnt;
    u8 lane_id;
    u8 lane_num;
    u8 rsvd0;

    struct mag_port_link_param default_cfg;
    struct mag_port_link_param bios_cfg;
    struct mag_port_link_param tool_cfg;
    struct mag_port_link_param final_cfg;

    struct mag_port_wire_info wire_info;
    struct mag_port_adapt_info adapt_info;
};

#define XSFP_VENDOR_NAME_LEN 16
struct mag_cmd_event_port_info {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 event_type;
    u8 rsvd0[2];

    // 光模块相关
    u8 vendor_name[XSFP_VENDOR_NAME_LEN];
    u32 port_type;     /* fiber / copper */
    u32 port_sub_type; /* sr / lr */
    u32 cable_length;  /* 1/3/5m */
    u8 cable_temp;     /* 温度 */
    u8 max_speed;      /* 光模块最大速率 */
    u8 sfp_type;       /* sfp/qsfp */
    u8 rsvd1;
    u32 power[4]; /* 光功率 */

    u8 an_state;
    u8 fec;
    u16 speed;

    u8 gpio_insert; /* 0:present  1:absent */
    u8 alos;
    u8 rx_los;
    u8 pma_ctrl;

    u32 pma_fifo_reg;
    u32 pma_signal_ok_reg;
    u32 pcs_64_66b_reg;
    u32 rf_lf;
    u8 pcs_link;
    u8 pcs_mac_link;
    u8 tx_enable;
    u8 rx_enable;
    u32 pcs_err_cnt;

    u8 eq_data[38];
    u8 rsvd2[2];

    u32 his_link_machine_state;
    u32 cur_link_machine_state;
    u8 his_machine_state_data[128];
    u8 cur_machine_state_data[128];
    u8 his_machine_state_length;
    u8 cur_machine_state_length;

    struct mag_port_param_info param_info;
    u8 rsvd3[360];
};

struct mag_cmd_port_stats {
    u64 mac_tx_fragment_pkt_num;
    u64 mac_tx_undersize_pkt_num;
    u64 mac_tx_undermin_pkt_num;
    u64 mac_tx_64_oct_pkt_num;
    u64 mac_tx_65_127_oct_pkt_num;
    u64 mac_tx_128_255_oct_pkt_num;
    u64 mac_tx_256_511_oct_pkt_num;
    u64 mac_tx_512_1023_oct_pkt_num;
    u64 mac_tx_1024_1518_oct_pkt_num;
    u64 mac_tx_1519_2047_oct_pkt_num;
    u64 mac_tx_2048_4095_oct_pkt_num;
    u64 mac_tx_4096_8191_oct_pkt_num;
    u64 mac_tx_8192_9216_oct_pkt_num;
    u64 mac_tx_9217_12287_oct_pkt_num;
    u64 mac_tx_12288_16383_oct_pkt_num;
    u64 mac_tx_1519_max_bad_pkt_num;
    u64 mac_tx_1519_max_good_pkt_num;
    u64 mac_tx_oversize_pkt_num;
    u64 mac_tx_jabber_pkt_num;
    u64 mac_tx_bad_pkt_num;
    u64 mac_tx_bad_oct_num;
    u64 mac_tx_good_pkt_num;
    u64 mac_tx_good_oct_num;
    u64 mac_tx_total_pkt_num;
    u64 mac_tx_total_oct_num;
    u64 mac_tx_uni_pkt_num;
    u64 mac_tx_multi_pkt_num;
    u64 mac_tx_broad_pkt_num;
    u64 mac_tx_pause_num;
    u64 mac_tx_pfc_pkt_num;
    u64 mac_tx_pfc_pri0_pkt_num;
    u64 mac_tx_pfc_pri1_pkt_num;
    u64 mac_tx_pfc_pri2_pkt_num;
    u64 mac_tx_pfc_pri3_pkt_num;
    u64 mac_tx_pfc_pri4_pkt_num;
    u64 mac_tx_pfc_pri5_pkt_num;
    u64 mac_tx_pfc_pri6_pkt_num;
    u64 mac_tx_pfc_pri7_pkt_num;
    u64 mac_tx_control_pkt_num;
    u64 mac_tx_err_all_pkt_num;
    u64 mac_tx_from_app_good_pkt_num;
    u64 mac_tx_from_app_bad_pkt_num;

    u64 mac_rx_fragment_pkt_num;
    u64 mac_rx_undersize_pkt_num;
    u64 mac_rx_undermin_pkt_num;
    u64 mac_rx_64_oct_pkt_num;
    u64 mac_rx_65_127_oct_pkt_num;
    u64 mac_rx_128_255_oct_pkt_num;
    u64 mac_rx_256_511_oct_pkt_num;
    u64 mac_rx_512_1023_oct_pkt_num;
    u64 mac_rx_1024_1518_oct_pkt_num;
    u64 mac_rx_1519_2047_oct_pkt_num;
    u64 mac_rx_2048_4095_oct_pkt_num;
    u64 mac_rx_4096_8191_oct_pkt_num;
    u64 mac_rx_8192_9216_oct_pkt_num;
    u64 mac_rx_9217_12287_oct_pkt_num;
    u64 mac_rx_12288_16383_oct_pkt_num;
    u64 mac_rx_1519_max_bad_pkt_num;
    u64 mac_rx_1519_max_good_pkt_num;
    u64 mac_rx_oversize_pkt_num;
    u64 mac_rx_jabber_pkt_num;
    u64 mac_rx_bad_pkt_num;
    u64 mac_rx_bad_oct_num;
    u64 mac_rx_good_pkt_num;
    u64 mac_rx_good_oct_num;
    u64 mac_rx_total_pkt_num;
    u64 mac_rx_total_oct_num;
    u64 mac_rx_uni_pkt_num;
    u64 mac_rx_multi_pkt_num;
    u64 mac_rx_broad_pkt_num;
    u64 mac_rx_pause_num;
    u64 mac_rx_pfc_pkt_num;
    u64 mac_rx_pfc_pri0_pkt_num;
    u64 mac_rx_pfc_pri1_pkt_num;
    u64 mac_rx_pfc_pri2_pkt_num;
    u64 mac_rx_pfc_pri3_pkt_num;
    u64 mac_rx_pfc_pri4_pkt_num;
    u64 mac_rx_pfc_pri5_pkt_num;
    u64 mac_rx_pfc_pri6_pkt_num;
    u64 mac_rx_pfc_pri7_pkt_num;
    u64 mac_rx_control_pkt_num;
    u64 mac_rx_sym_err_pkt_num;
    u64 mac_rx_fcs_err_pkt_num;
    u64 mac_rx_send_app_good_pkt_num;
    u64 mac_rx_send_app_bad_pkt_num;
    u64 mac_rx_unfilter_pkt_num;
};

struct mag_cmd_port_stats_info {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 rsvd0[3];
};

struct mag_cmd_get_port_stat {
    struct ssshw_mgmt_msg_head head;

    struct mag_cmd_port_stats counter;
    u64 rsvd1[15];
};

struct mag_cmd_get_pcs_err_cnt {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 rsvd0[3];

    u32 pcs_err_cnt;
};

struct mag_cmd_get_mag_cnt {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 len;
    u8 rsvd0[2];

    u32 mag_csr[128];
};

struct mag_cmd_dump_antrain_info {
    struct ssshw_mgmt_msg_head head;

    u8 port_id;
    u8 len;
    u8 rsvd0[2];

    u32 antrain_csr[256];
};

#define MAG_SFP_PORT_NUM 24
/* 芯片光模块温度结构体定义 */
struct mag_cmd_sfp_temp_in_info {
    struct ssshw_mgmt_msg_head head; /* 8B */
    u8 opt_type;               /* 0:read operation 1:cfg operation */
    u8 rsv[3];
    s32 max_temp; /* 芯片光模块阈值 */
    s32 min_temp; /* 芯片光模块阈值 */
};

struct mag_cmd_sfp_temp_out_info {
    struct ssshw_mgmt_msg_head head;          /* 8B */
    s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* 读出的温度 */
    s32 max_temp;                        /* 芯片光模块阈值 */
    s32 min_temp;                        /* 芯片光模块阈值 */
};



#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif

#define SSSNIC_CMD_OP_SET	1
#define SSSNIC_CMD_OP_GET	0

#define SSSNIC_CMD_OP_ADD	1
#define SSSNIC_CMD_OP_DEL	0

#ifndef BIT
#define BIT(n) (1UL << (n))
#endif

enum nic_feature_cap {
    NIC_F_CSUM = BIT(0),
    NIC_F_SCTP_CRC = BIT(1),
    NIC_F_TSO = BIT(2),
    NIC_F_LRO = BIT(3),
    NIC_F_UFO = BIT(4),
    NIC_F_RSS = BIT(5),
    NIC_F_RX_VLAN_FILTER = BIT(6),
    NIC_F_RX_VLAN_STRIP = BIT(7),
    NIC_F_TX_VLAN_INSERT = BIT(8),
    NIC_F_VXLAN_OFFLOAD = BIT(9),
    NIC_F_IPSEC_OFFLOAD = BIT(10),
    NIC_F_FDIR = BIT(11),
    NIC_F_PROMISC = BIT(12),
    NIC_F_ALLMULTI = BIT(13),
    NIC_F_XSFP_REPORT = BIT(14),
    NIC_F_VF_MAC = BIT(15),
    NIC_F_RATE_LIMIT = BIT(16),
};

#define NIC_F_ALL_MASK 0x1FFFF /* 使能所有属性 */

struct sssnic_mgmt_msg_head {
    u8 status;
    u8 version;
    u8 rsvd0[6];
};

#define NIC_MAX_FEATURE_QWORD	4
struct sssnic_cmd_feature_nego {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u8 opcode; /* 1: set, 0: get */
    u8 rsvd;
    u64 s_feature[NIC_MAX_FEATURE_QWORD];
};

struct sssnic_port_mac_set {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u16 vlan_id;
    u16 rsvd1;
    u8 mac[ETH_ALEN];
};

struct sssnic_port_mac_update {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u16 vlan_id;
    u16 rsvd1;
    u8 old_mac[ETH_ALEN];
    u16 rsvd2;
    u8 new_mac[ETH_ALEN];
};

struct sssnic_vport_state {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u16 rsvd1;
    u8 state; /* 0--disable, 1--enable */
    u8 rsvd2[3];
};

struct sssnic_port_state {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u16 rsvd1;
    u8 state; /* 0--disable, 1--enable */
    u8 rsvd2[3];
};

struct sssnic_cmd_clear_qp_resource {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u16 rsvd1;
};

struct sssnic_port_stats_info {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u16 rsvd1;
};

struct sssnic_vport_stats {
    u64 tx_unicast_pkts_vport;
    u64 tx_unicast_bytes_vport;
    u64 tx_multicast_pkts_vport;
    u64 tx_multicast_bytes_vport;
    u64 tx_broadcast_pkts_vport;
    u64 tx_broadcast_bytes_vport;

    u64 rx_unicast_pkts_vport;
    u64 rx_unicast_bytes_vport;
    u64 rx_multicast_pkts_vport;
    u64 rx_multicast_bytes_vport;
    u64 rx_broadcast_pkts_vport;
    u64 rx_broadcast_bytes_vport;

    u64 tx_discard_vport;
    u64 rx_discard_vport;
    u64 tx_err_vport;
    u64 rx_err_vport;
};

struct sssnic_phy_fpga_port_stats {
    u64 mac_rx_total_octs_port;
    u64 mac_tx_total_octs_port;
    u64 mac_rx_under_frame_pkts_port;
    u64 mac_rx_frag_pkts_port;
    u64 mac_rx_64_oct_pkts_port;
    u64 mac_rx_127_oct_pkts_port;
    u64 mac_rx_255_oct_pkts_port;
    u64 mac_rx_511_oct_pkts_port;
    u64 mac_rx_1023_oct_pkts_port;
    u64 mac_rx_max_oct_pkts_port;
    u64 mac_rx_over_oct_pkts_port;
    u64 mac_tx_64_oct_pkts_port;
    u64 mac_tx_127_oct_pkts_port;
    u64 mac_tx_255_oct_pkts_port;
    u64 mac_tx_511_oct_pkts_port;
    u64 mac_tx_1023_oct_pkts_port;
    u64 mac_tx_max_oct_pkts_port;
    u64 mac_tx_over_oct_pkts_port;
    u64 mac_rx_good_pkts_port;
    u64 mac_rx_crc_error_pkts_port;
    u64 mac_rx_broadcast_ok_port;
    u64 mac_rx_multicast_ok_port;
    u64 mac_rx_mac_frame_ok_port;
    u64 mac_rx_length_err_pkts_port;
    u64 mac_rx_vlan_pkts_port;
    u64 mac_rx_pause_pkts_port;
    u64 mac_rx_unknown_mac_frame_port;
    u64 mac_tx_good_pkts_port;
    u64 mac_tx_broadcast_ok_port;
    u64 mac_tx_multicast_ok_port;
    u64 mac_tx_underrun_pkts_port;
    u64 mac_tx_mac_frame_ok_port;
    u64 mac_tx_vlan_pkts_port;
    u64 mac_tx_pause_pkts_port;
};

struct sssnic_port_stats {
    struct sssnic_mgmt_msg_head msg_head;

    struct sssnic_phy_fpga_port_stats stats;
};

struct sssnic_cmd_vport_stats {
	struct sssnic_mgmt_msg_head msg_head;

	u32 stats_size;
	u32 rsvd1;
	struct sssnic_vport_stats stats;
	u64 rsvd2[6];
};

struct sssnic_cmd_qpn {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u16 base_qpn;
};

enum sssnic_func_tbl_cfg_bitmap {
	FUNC_CFG_INIT,
	FUNC_CFG_RX_BUF_SIZE,
	FUNC_CFG_MTU,
};

struct sssnic_func_tbl_cfg {
	u16 rx_wqe_buf_size;
	u16 mtu;
	u32 rsvd[9];
};

struct sssnic_cmd_set_func_tbl {
	struct sssnic_mgmt_msg_head msg_head;

	u16 func_id;
	u16 rsvd;

	u32 cfg_bitmap;
	struct sssnic_func_tbl_cfg tbl_cfg;
};

struct sssnic_cmd_cons_idx_attr {
	struct sssnic_mgmt_msg_head msg_head;

	u16 func_idx;
	u8 dma_attr_off;
	u8 pending_limit;
	u8 coalescing_time;
	u8 intr_en;
	u16 intr_idx;
	u32 l2nic_sqn;
	u32 rsvd;
	u64 ci_addr;
};

typedef union {
    struct {
        u32 tbl_index;
        u32 cnt;
        u32 total_cnt;
    } mac_table_arg;
    struct {
        u32 er_id;
        u32 vlan_id;
    } vlan_elb_table_arg;
    struct {
        u32 func_id;
    } vlan_filter_arg;
    struct {
        u32 mc_id;
    } mc_elb_arg;
    struct {
        u32 func_id;
    } func_tbl_arg;
    struct {
        u32 port_id;
    } port_tbl_arg;
    struct {
        u32 tbl_index;
        u32 cnt;
        u32 total_cnt;
    } fdir_io_table_arg;
    struct {
        u32 tbl_index;
        u32 cnt;
        u32 total_cnt;
    } flexq_table_arg;
    u32 args[4];
} sm_tbl_args;

#define DFX_SM_TBL_BUF_MAX (768)

struct sssnic_cmd_dfx_sm_table {
    struct sssnic_mgmt_msg_head msg_head;
    u32 tbl_type;
    sm_tbl_args args;
    u8 tbl_buf[DFX_SM_TBL_BUF_MAX];
};

struct sssnic_cmd_vlan_offload {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u8 vlan_offload;
    u8 rsvd1[5];
};

/* ucode capture cfg info */
struct sssnic_cmd_capture_info {
    struct sssnic_mgmt_msg_head msg_head;
    u32 op_type;
    u32 func_port;
    u32 is_en_trx;       /* 也作为tx_rx */
    u32 offset_cos;      /* 也作为cos */
    u32 data_vlan;       /* 也作为vlan */
};

struct sssnic_cmd_lro_config {
	struct sssnic_mgmt_msg_head msg_head;

	u16 func_id;
	u8 opcode;
	u8 rsvd1;
	u8 lro_ipv4_en;
	u8 lro_ipv6_en;
	u8 lro_max_pkt_len; /* unit is 1K */
	u8 resv2[13];
};

struct sssnic_cmd_lro_timer {
	struct sssnic_mgmt_msg_head msg_head;

	u8 opcode; /* 1: set timer value, 0: get timer value */
	u8 rsvd1;
	u16 rsvd2;
	u32 timer;
};

struct sssnic_cmd_vf_vlan_config {
	struct sssnic_mgmt_msg_head msg_head;

	u16 func_id;
	u8 opcode;
	u8 rsvd1;
	u16 vlan_id;
	u8 qos;
	u8 rsvd2[5];
};

struct sssnic_cmd_spoofchk_set {
	struct sssnic_mgmt_msg_head msg_head;

	u16 func_id;
	u8 state;
	u8 rsvd1;
};

struct sssnic_cmd_tx_rate_cfg {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u16 rsvd1;
    u32 min_rate;
    u32 max_rate;
    u8 rsvd2[8];
};

struct sssnic_cmd_port_info {
    struct sssnic_mgmt_msg_head msg_head;

    u8 port_id;
    u8 rsvd1[3];
    u8 port_type;
    u8 autoneg_cap;
    u8 autoneg_state;
    u8 duplex;
    u8 speed;
    u8 fec;
    u16 rsvd2;
    u32 rsvd3[4];
};

struct sssnic_cmd_register_vf {
    struct sssnic_mgmt_msg_head msg_head;

    u8 op_register; /* 0 - unregister, 1 - register */
    u8 rsvd1[3];
    u32 support_extra_feature;
    u8 rsvd2[32];
};

struct sssnic_cmd_link_state {
    struct sssnic_mgmt_msg_head msg_head;

    u8 port_id;
    u8 state;
    u16 rsvd1;
};

struct sssnic_cmd_vlan_config {
	struct sssnic_mgmt_msg_head msg_head;

	u16 func_id;
	u8 opcode;
	u8 rsvd1;
	u16 vlan_id;
	u16 rsvd2;
};

/* set vlan filter */
struct sssnic_cmd_set_vlan_filter {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u8 resvd[2];
    u32 vlan_filter_ctrl; /* bit0:vlan filter en; bit1:broadcast_filter_en */
};

struct sssnic_cmd_link_ksettings_info {
    struct sssnic_mgmt_msg_head msg_head;

    u8 port_id;
    u8 rsvd1[3];

    u32 valid_bitmap;
    u8 speed;          /* enum nic_speed_level */
    u8 autoneg;        /* 0 - off, 1 - on */
    u8 fec;            /* 0 - RSFEC, 1 - BASEFEC, 2 - NOFEC */
    u8 rsvd2[21];      /* reserved for duplex, port, etc. */
};

struct mpu_lt_info {
    u8 node;
    u8 inst;
    u8 entry_size;
    u8 rsvd;
    u32 lt_index;
    u32 offset;
    u32 len;
};

struct sssnic_mpu_lt_opera {
    struct sssnic_mgmt_msg_head msg_head;
    struct mpu_lt_info net_lt_cmd;
    u8 data[100];
};

struct sssnic_rx_mode_config {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u16 rsvd1;
    u32 rx_mode;
};

/* rss */
struct sssnic_rss_context_table {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u16 rsvd1;
    u32 context;
};


struct sssnic_cmd_rss_engine_type {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u8 opcode;
    u8 hash_engine;
    u8 rsvd1[4];
};


struct sssnic_cmd_rss_hash_key {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u8 opcode;
    u8 rsvd1;
    u8 key[SSSNIC_RSS_KEY_SIZE];
};


struct sssnic_rss_indir_table {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u16 rsvd1;
    u8 indir[SSSNIC_RSS_INDIR_SIZE];
};

#define NIC_RSS_CMD_TEMP_ALLOC 0x01
#define NIC_RSS_CMD_TEMP_FREE 0x02

struct sssnic_rss_template_mgmt {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u8 cmd;
    u8 template_id;
    u8 rsvd1[4];
};


struct sssnic_cmd_rss_config {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u8 rss_en;
    u8 rq_priority_number;
    u8 prio_tc[SSSNIC_DCB_COS_MAX];
    u16 num_qps;
    u16 rsvd1;
};

struct sssnic_dcb_state {
	u8 dcb_on;
	u8 default_cos;
	u8 trust;
	u8 rsvd1;
	u8 pcp2cos[SSSNIC_DCB_UP_MAX];
	u8 dscp2cos[64];
	u32 rsvd2[7];
};

struct sssnic_cmd_vf_dcb_state {
	struct sssnic_mgmt_msg_head msg_head;

	struct sssnic_dcb_state state;
};

struct sssnic_up_ets_cfg { /* delet */
    struct sssnic_mgmt_msg_head msg_head;

    u8 port_id;
    u8 rsvd1[3];

    u8 cos_tc[SSSNIC_DCB_COS_MAX];
    u8 tc_bw[SSSNIC_DCB_TC_MAX];
    u8 cos_prio[SSSNIC_DCB_COS_MAX];
    u8 cos_bw[SSSNIC_DCB_COS_MAX];
    u8 tc_prio[SSSNIC_DCB_TC_MAX];
};

#define CMD_QOS_ETS_COS_TC     BIT(0)
#define CMD_QOS_ETS_TC_BW      BIT(1)
#define CMD_QOS_ETS_COS_PRIO   BIT(2)
#define CMD_QOS_ETS_COS_BW     BIT(3)
#define CMD_QOS_ETS_TC_PRIO    BIT(4)
struct sssnic_cmd_ets_cfg {
    struct sssnic_mgmt_msg_head head;

    u8 port_id;
    u8 op_code;        /* 1 - set, 0 - get */
    u8 cfg_bitmap;     /* bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio, bit3 - cos_bw, bit4 - tc_prio */
    u8 rsvd;

    u8 cos_tc[SSSNIC_DCB_COS_MAX];
    u8 tc_bw[SSSNIC_DCB_TC_MAX];
    u8 cos_prio[SSSNIC_DCB_COS_MAX];      /* 0 - DWRR, 1 - STRICT */
    u8 cos_bw[SSSNIC_DCB_COS_MAX];
    u8 tc_prio[SSSNIC_DCB_TC_MAX];        /* 0 - DWRR, 1 - STRICT */
};

struct sssnic_cmd_set_dcb_state {
    struct sssnic_mgmt_msg_head head;

    u16 func_id;
    u8 op_code;      /* 0 - get dcb state, 1 - set dcb state */
    u8 state;        /* 0 - disable, 1 - enable dcb */
    u8 port_state;   /* 0 - disable, 1 - enable dcb */
    u8 rsvd[7];
};

#define PFC_BIT_MAP_NUM 8
struct sssnic_cmd_set_pfc {
    struct sssnic_mgmt_msg_head head;

    u8 port_id;
    u8 op_code;  /* 0：get 1: set pfc_en  2: set pfc_bitmap 3: set all */
    u8 pfc_en;   /* pfc_en 和 pfc_bitmap 必须同时设置 */
    u8 pfc_bitmap;
    u8 rsvd[4];
};

#define CMD_QOS_PORT_TRUST     BIT(0)
#define CMD_QOS_PORT_DFT_COS   BIT(1)
struct sssnic_cmd_qos_port_cfg {
    struct sssnic_mgmt_msg_head head;

    u8 port_id;
    u8 op_code;       /* 0 - get, 1 - set */
    u8 cfg_bitmap;    /* bit0 - trust, bit1 - dft_cos */
    u8 rsvd0;

    u8 trust;
    u8 dft_cos;
    u8 rsvd1[18];
};

#define MAP_COS_MAX_NUM 8
#define CMD_QOS_MAP_PCP2COS     BIT(0)
#define CMD_QOS_MAP_DSCP2COS    BIT(1)
struct sssnic_cmd_qos_map_cfg {
    struct sssnic_mgmt_msg_head head;

    u8 op_code;
    u8 cfg_bitmap; /* bit0 - pcp2cos, bit1 - dscp2cos */
    u16 rsvd0;

    u8 pcp2cos[8]; /* 必须8个一起配置 */
    u8 dscp2cos[64]; /* 配置dscp2cos时，若cos值设置为0xFF，MPU则忽略此dscp优先级的配置，允许一次性配置多个dscp跟cos的映射关系
                      */
    u32 rsvd1[4];
};

struct sssnic_cos_up_map {
    struct sssnic_mgmt_msg_head msg_head;

    u8 port_id;
    u8 cos_valid_mask; /* every bit indicate index of map is valid 1 or not 0 */
    u16 rsvd1;

    /* user priority in cos(index:cos, value: up pri) */
    u8 map[SSSNIC_DCB_UP_MAX];
};

struct sssnic_cmd_pause_config {
    struct sssnic_mgmt_msg_head msg_head;

    u8 port_id;
    u8 opcode;
    u16 rsvd1;
    u8 auto_neg;
    u8 rx_pause;
    u8 tx_pause;
    u8 rsvd2[5];
};

/* pfc风暴检测配置 */
struct sssnic_cmd_pause_inquiry_cfg {
    struct sssnic_mgmt_msg_head head;

    u32 valid;

    u32 type; /* 1: set, 2: get */

    u32 rx_inquiry_pause_drop_pkts_en; /* rx 卸包使能 */
    u32 rx_inquiry_pause_period_ms;  /* rx pause 检测周期 默认 200ms */
    u32 rx_inquiry_pause_times;      /* rx pause 检测次数 默认1次 */
    u32 rx_inquiry_pause_frame_thd;  /* rx pause 检测阈值 默认 PAUSE_FRAME_THD_10G/25G/40G/100 */
    u32 rx_inquiry_tx_total_pkts;    /* rx pause 检测tx收包总数 */

    u32 tx_inquiry_pause_en; /* tx pause 检测使能 */
    u32 tx_inquiry_pause_period_ms;  /* tx pause 检测周期 默认 200ms */
    u32 tx_inquiry_pause_times;      /* tx pause 检测次数 默认 5次 */
    u32 tx_inquiry_pause_frame_thd;  /* tx pause 检测阈值 */
    u32 tx_inquiry_rx_total_pkts;    /* tx pause 检测rx收包总数 */

    u32 rsvd[4];
};

/* pfc/pause风暴tx异常上报 */
struct sssnic_cmd_tx_pause_notice {
    struct sssnic_mgmt_msg_head head;

    u32 tx_pause_except; /* 1: 异常，0: 正常 */
    u32 except_level;
    u32 rsvd;
};

#define SSSNIC_CMD_OP_FREE 0
#define SSSNIC_CMD_OP_ALLOC 1

struct sssnic_cmd_cfg_qps {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u8 opcode; /* 1: alloc qp, 0: free qp */
    u8 rsvd1;
    u16 num_qps;
    u16 rsvd2;
};

struct sssnic_cmd_led_config {
    struct sssnic_mgmt_msg_head msg_head;

    u8 port;
    u8 type;
    u8 mode;
    u8 rsvd1;
};

struct sssnic_cmd_port_loopback {
    struct sssnic_mgmt_msg_head msg_head;

    u8 port_id;
    u8 opcode;
    u8 mode;
    u8 en;
    u32 rsvd1[2];
};

struct sssnic_cmd_get_light_module_abs {
    struct sssnic_mgmt_msg_head msg_head;

    u8 port_id;
    u8 abs_status; /* 0:present, 1:absent */
    u8 rsv[2];
};

#define STD_SFP_INFO_MAX_SIZE 640
struct sssnic_cmd_get_std_sfp_info {
    struct sssnic_mgmt_msg_head msg_head;

    u8 port_id;
    u8 wire_type;
    u16 eeprom_len;
    u32 rsvd;
    u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
};

struct sssnic_cable_plug_event {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u8 plugged; /* 0: unplugged, 1: plugged */
    u8 port_id;
};

/* MAC模块接口 */
struct sssnic_cmd_mac_info {
    struct sssnic_mgmt_msg_head head;

    u32 valid_bitmap;
    u16 rsvd;

    u8 host_id[32];
    u8 port_id[32];
    u8 mac_addr[192];
};

struct sssnic_cmd_set_tcam_enable {
	struct sssnic_mgmt_msg_head head;

	u16 func_id;
	u8 tcam_enable;
	u8 rsvd1;
	u32 rsvd2;
};

struct sssnic_cmd_set_fdir_status {
    struct sssnic_mgmt_msg_head head;

    u16 func_id;
    u16 rsvd1;
    u8 pkt_type_en;
    u8 pkt_type;
    u8 qid;
    u8 rsvd2;
};

#define SSSNIC_TCAM_BLOCK_ENABLE      1
#define SSSNIC_TCAM_BLOCK_DISABLE     0
#define SSSNIC_MAX_TCAM_RULES_NUM   4096

/* tcam block type, acording to tcam block size */
enum {
    NIC_TCAM_BLOCK_TYPE_LARGE = 0, /* block_size: 16 */
    NIC_TCAM_BLOCK_TYPE_SMALL,     /* block_size: 0 */
    NIC_TCAM_BLOCK_TYPE_MAX
};

/* alloc tcam block input struct */
struct sssnic_cmd_ctrl_tcam_block_in {
    struct sssnic_mgmt_msg_head head;

    u16 func_id;  /* func_id */
    u8 alloc_en;  /* 0: 释放分配的tcam block, 1: 申请新的tcam block */
    u8 tcam_type; /* 0: 分配16 size 的tcam block, 1: 分配0 size的tcam block, 其他预留 */
    u16 tcam_block_index;
    u16 alloc_block_num; /* 驱动发给uP表示驱动希望分配的block大小
                          * uP返回给驱动的接口，表示uP 支持的分配的tcam block大小 */
};

/* alloc tcam block output struct */
struct sssnic_cmd_ctrl_tcam_block_out {
    struct sssnic_mgmt_msg_head head;

    u16 func_id;  /* func_id */
    u8 alloc_en;  /* 0: 释放分配的tcam block, 1: 申请新的tcam block */
    u8 tcam_type; /* 0: 分配16 size 的tcam block, 1: 分配0 size的tcam block, 其他预留 */
    u16 tcam_block_index;
    u16 mpu_alloc_block_size; /* 驱动发给uP表示驱动希望分配的block大小
                               * uP返回给驱动的接口，表示uP 支持的分配的tcam block大小 */
};

struct sssnic_cmd_flush_tcam_rules {
    struct sssnic_mgmt_msg_head head;

    u16 func_id; /* func_id */
    u16 rsvd;
};

struct sssnic_cmd_dfx_fdir_tcam_block_table {
    struct sssnic_mgmt_msg_head head;
    u8 tcam_type;
    u8 valid;
    u16 tcam_block_index;
    u16 use_function_id;
    u16 rsvd;
};

struct tcam_result {
    u32 qid;
    u32 rsvd;
};

#define TCAM_FLOW_KEY_SIZE (44)

struct tcam_key_x_y {
    u8 x[TCAM_FLOW_KEY_SIZE];
    u8 y[TCAM_FLOW_KEY_SIZE];
};

struct sssnic_tcam_cfg_rule {
    u32 index;
    struct tcam_result data;
    struct tcam_key_x_y key;
};

#define TCAM_RULE_FDIR_TYPE 0
#define TCAM_RULE_DPI_TYPE  1

struct sssnic_cmd_fdir_add_rule {
    struct sssnic_mgmt_msg_head head;

    u16 func_id;
    u8 type;
    u8 rsvd;
    struct sssnic_tcam_cfg_rule rule;
};

struct sssnic_cmd_fdir_del_rules {
    struct sssnic_mgmt_msg_head head;

    u16 func_id;
    u8 type;
    u8 rsvd;
    u32 index_start;
    u32 index_num;
};

struct sssnic_cmd_fdir_get_rule {
    struct sssnic_mgmt_msg_head head;

    u32 index;
    u8 valid;
    u8 type;
    u16 rsvd;
    struct tcam_key_x_y key;
    struct tcam_result data;
    u64 packet_count;
    u64 byte_count;
};

struct sssnic_tcam_key_ipv4_mem {
    u32 rsvd1 : 4;
    u32 tunnel_type : 4;
    u32 ip_proto : 8;
    u32 rsvd0 : 16;
    u32 sipv4_h : 16;
    u32 ip_type : 1;
    u32 function_id : 15;
    u32 dipv4_h : 16;
    u32 sipv4_l : 16;
    u32 rsvd2 : 16;
    u32 dipv4_l : 16;
    u32 rsvd3;
    u32 dport : 16;
    u32 rsvd4 : 16;
    u32 rsvd5 : 16;
    u32 sport : 16;
    u32 outer_sipv4_h : 16;
    u32 rsvd6 : 16;
    u32 outer_dipv4_h : 16;
    u32 outer_sipv4_l : 16;
    u32 vni_h : 16;
    u32 outer_dipv4_l : 16;
    u32 rsvd7 : 16;
    u32 vni_l : 16;
};

struct sssnic_tcam_key_ipv6_mem {
    u32 rsvd1 : 4;
    u32 tunnel_type : 4;
    u32 ip_proto : 8;
    u32 rsvd0 : 16;
    u32 sipv6_key0 : 16;
    u32 ip_type : 1;
    u32 function_id : 15;
    u32 sipv6_key2 : 16;
    u32 sipv6_key1 : 16;
    u32 sipv6_key4 : 16;
    u32 sipv6_key3 : 16;
    u32 sipv6_key6 : 16;
    u32 sipv6_key5 : 16;
    u32 dport : 16;
    u32 sipv6_key7 : 16;
    u32 dipv6_key0 : 16;
    u32 sport : 16;
    u32 dipv6_key2 : 16;
    u32 dipv6_key1 : 16;
    u32 dipv6_key4 : 16;
    u32 dipv6_key3 : 16;
    u32 dipv6_key6 : 16;
    u32 dipv6_key5 : 16;
    u32 rsvd2 : 16;
    u32 dipv6_key7 : 16;
};

struct tag_tcam_key {
    union {
        struct sssnic_tcam_key_ipv4_mem key_info;
        struct sssnic_tcam_key_ipv6_mem key_info_ipv6;
    };

    union {
        struct sssnic_tcam_key_ipv4_mem key_mask;
        struct sssnic_tcam_key_ipv6_mem key_mask_ipv6;
    };
};

enum {
    DPI_TABLE_ID_CLEAN_CMD = 0,
    DPI_TABLE_ID_ADD_CMD,
    DPI_TABLE_ID_DEL_CMD,
    FDIR_TABLE_ID_ADD_CMD,
    FDIR_TABLE_ID_DEL_CMD,
    DPI_TABEL_ID_MAX
};

struct sssnic_dpi_cfg_table_id_cmd {
    struct sssnic_mgmt_msg_head msg_head;

    u16 rsvd0;
    u16 cmd;
    u16 table_id;
    u16 rsvd1;
};

struct sssnic_dpi_cfg_dpi_en_cmd {
    struct sssnic_mgmt_msg_head msg_head;

    u16 func_id;
    u8 dpi_en;
    u8 rsvd;
};

struct sssnic_dpi_cfg_mode_cmd {
    struct sssnic_mgmt_msg_head msg_head;

    u16 rsvd0;
    u8 dpi_mode;
    u8 qpc_func_nums;
    u16 base_qpc_func_id;
    u16 rsvd1;
};

struct sssnic_dpi_flush_en_cmd {
    struct sssnic_mgmt_msg_head msg_head;

    u16 rsvd0;
    u8 flush_en; /* 0 flush done, 1 in flush operation */
    u8 rsvd1;
};

struct sssnic_dpi_fdir_query_cmd {
    struct sssnic_mgmt_msg_head msg_head;

    u32 index;
    u32 rsvd;
    u64 pkt_nums;
    u64 pkt_bytes;
};

/* BIOS CONF */
enum {
    NIC_NVM_DATA_SET = BIT(0), /* 1-save, 0-read */
    NIC_NVM_DATA_PXE = BIT(1),
    NIC_NVM_DATA_VLAN = BIT(2),
    NIC_NVM_DATA_VLAN_PRI = BIT(3),
    NIC_NVM_DATA_VLAN_ID = BIT(4),
    NIC_NVM_DATA_WORK_MODE = BIT(5),
    NIC_NVM_DATA_PF_SPEED_LIMIT = BIT(6),
    NIC_NVM_DATA_GE_MODE = BIT(7),
    NIC_NVM_DATA_AUTO_NEG = BIT(8),
    NIC_NVM_DATA_LINK_FEC = BIT(9),
    NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
    NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
    NIC_NVM_DATA_EXTEND_MODE = BIT(12),
    NIC_NVM_DATA_RESET = BIT(31),
};

#define BIOS_CFG_SIGNATURE                  0x1923E518
#define BIOS_OP_CFG_ALL(op_code_val)        (((op_code_val) >> 1) & (0xFFFFFFFF))
#define BIOS_OP_CFG_WRITE(op_code_val)      ((op_code_val) & NIC_NVM_DATA_SET)
#define BIOS_OP_CFG_PXE_EN(op_code_val)     ((op_code_val) & NIC_NVM_DATA_PXE)
#define BIOS_OP_CFG_VLAN_EN(op_code_val)    ((op_code_val) & NIC_NVM_DATA_VLAN)
#define BIOS_OP_CFG_VLAN_PRI(op_code_val)   ((op_code_val) & NIC_NVM_DATA_VLAN_PRI)
#define BIOS_OP_CFG_VLAN_ID(op_code_val)    ((op_code_val) & NIC_NVM_DATA_VLAN_ID)
#define BIOS_OP_CFG_WORK_MODE(op_code_val)  ((op_code_val) & NIC_NVM_DATA_WORK_MODE)
#define BIOS_OP_CFG_PF_BW(op_code_val)      ((op_code_val) & NIC_NVM_DATA_PF_SPEED_LIMIT)
#define BIOS_OP_CFG_GE_SPEED(op_code_val)   ((op_code_val) & NIC_NVM_DATA_GE_MODE)
#define BIOS_OP_CFG_AUTO_NEG(op_code_val)   ((op_code_val) & NIC_NVM_DATA_AUTO_NEG)
#define BIOS_OP_CFG_LINK_FEC(op_code_val)   ((op_code_val) & NIC_NVM_DATA_LINK_FEC)
#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) ((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK)
#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val)   ((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL)
#define BIOS_OP_CFG_EXTEND_MODE(op_code_val)    ((op_code_val) & NIC_NVM_DATA_EXTEND_MODE)
#define BIOS_OP_CFG_RST_DEF_SET(op_code_val)    ((op_code_val) & (u32)NIC_NVM_DATA_RESET)

/* 注意:此结构必须保证4字节对齐 */
struct sssnic_bios_cfg {
    u32 signature; /* 签名，用于判断FLASH的内容合法性 */
    u8 pxe_en;     /* PXE enable: 0 - disable 1 - enable */
    u8 extend_mode;
    u8 rsvd0[2];
    u8 pxe_vlan_en;     /* PXE VLAN enable: 0 - disable 1 - enable */
    u8 pxe_vlan_pri;    /* PXE VLAN priority: 0-7 */
    u16 pxe_vlan_id;    /* PXE VLAN ID 1-4094 */
    u32 service_mode;   /* 参考CHIPIF_SERVICE_MODE_x 宏 */
    u32 pf_bw;          /* PF速率，百分比 0-100 */
    u8 speed;           /* enum of port speed */
    u8 auto_neg;        /* 自协商开关 0 - 字段无效 1 - 开2 - 关 */
    u8 lanes;           /* lane num */
    u8 fec;             /* FEC模式, 参考 enum mag_cmd_port_fec */
    u8 auto_adapt;      /* 自适应模式配置0 - 无效配置 1 - 开启 2 - 关闭 */
    u8 func_valid;      /* 指示func_id是否有效; 0 - 无效，other - 有效 */
    u8 func_id;         /* 当func_valid不为0时，该成员才有意义 */
    u8 sriov_en;        /* SRIOV-EN: 0 - 无效配置， 1 - 开启， 2 - 关闭 */
};

struct sssnic_cmd_bios_cfg {
    struct sssnic_mgmt_msg_head head;
    u32 op_code; /* Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
    struct sssnic_bios_cfg bios_cfg;
};

struct sssnic_cmd_vhd_config {
    struct sssnic_mgmt_msg_head head;

    u16 func_id;
    u8  vhd_type;
    u8  virtio_small_enable;    /* 0: mergeable mode, 1: small mode */
};

/* BOND */
struct sssnic_create_bond_info {
    u32 bond_id;              /* bond设备号,output时有效,mpu操作成功返回时回填 */
    u32 master_slave_port_id; /*  */
    u32 slave_bitmap;         /* bond port id bitmap */
    u32 poll_timeout;         /* bond设备链路检查时间 */
    u32 up_delay;             /* 暂时预留 */
    u32 down_delay;           /* 暂时预留 */
    u32 bond_mode;            /* 暂时预留 */
    u32 active_pf; /* bond使用的active pf id */
    u32 active_port_max_num; /* bond活动成员口个数上限 */
    u32 active_port_min_num; /* bond活动成员口个数下限 */
    u32 xmit_hash_policy; /* hash策略，用于微码选路逻辑 */
    u32 rsvd[2];
};

/* 创建bond的消息接口 */
struct sssnic_cmd_create_bond {
    struct sssnic_mgmt_msg_head head;
    struct sssnic_create_bond_info create_bond_info;
};

struct sssnic_cmd_delete_bond {
    struct sssnic_mgmt_msg_head head;
    u32 bond_id;
    u32 rsvd[2];
};

struct sssnic_open_close_bond_info {
    u32 bond_id;                 /* bond设备号 */
    u32 open_close_flag;         /* 开启/关闭bond标识:1为open, 0为close */
    u32 rsvd[2];
};

/* MPU bond的消息接口 */
struct sssnic_cmd_open_close_bond {
    struct sssnic_mgmt_msg_head head;
    struct sssnic_open_close_bond_info open_close_bond_info;
};

/* LACPDU的port相关字段 */
struct lacp_port_params {
    u16 port_number;
    u16 port_priority;
    u16 key;
    u16 system_priority;
    u8 system[ETH_ALEN];
    u8 port_state;
    u8 rsvd;
};

struct lacp_port_info {
    u32 selected;
    u32 aggregator_port_id;           /* 使用的 aggregator port ID */

    struct lacp_port_params actor;    /* actor port参数 */
    struct lacp_port_params partner;  /* partner port参数 */

    u64 tx_lacp_pkts;
    u64 rx_lacp_pkts;
    u64 rx_8023ad_drop;
    u64 tx_8023ad_drop;
    u64 unknown_pkt_drop;
    u64 rx_marker_pkts;
    u64 tx_marker_pkts;
};

/* lacp 状态信息 */
struct sssnic_bond_status_info {
    struct sssnic_mgmt_msg_head head;
    u32 bond_id;
    u32 bon_mmi_status; /* 该bond子设备的链路状态 */
    u32 active_bitmap;  /* 该bond子设备的slave port状态 */
    u32 port_count;     /* 该bond子设备个数 */

    struct lacp_port_info port_info[4];

    u64 success_report_cnt[4]; /* 每个host成功上报lacp协商结果次数 */
    u64 fail_report_cnt[4];    /* 每个host上报lacp协商结果失败次数 */

    u64 poll_timeout;
    u64 fast_periodic_timeout;
    u64 slow_periodic_timeout;
    u64 short_timeout;
    u64 long_timeout;
    u64 aggregate_wait_timeout;
    u64 tx_period_timeout;
    u64 rx_marker_timer;
};

/* lacp协商结果更新之后向主机侧发送异步消息通知结构体 */
struct sssnic_bond_active_report_info {
    struct sssnic_mgmt_msg_head head;
    u32 bond_id;
    u32 bon_mmi_status; /* 该bond子设备的链路状态 */
    u32 active_bitmap;  /* 该bond子设备的slave port状态 */

    u8 rsvd[16];
};

/* IP checksum error packets, enable rss quadruple hash. */
struct sssnic_ipcs_err_rss_enable_operation_s {
    struct sssnic_mgmt_msg_head head;

    u8 en_tag;
    u8 type; /* 1: set  0: get */
    u8 rsvd[3];
};

struct sssnic_smac_check_state {
    struct sssnic_mgmt_msg_head head;
    u8 smac_check_en; /* 1: enable 0: disable */
    u8 op_code; /* 1: set 0: get */
    u8 rsvd[2];
};


struct sssnic_rss_type {
	u8 tcp_ipv6_ext;
	u8 ipv6_ext;
	u8 tcp_ipv6;
	u8 ipv6;
	u8 tcp_ipv4;
	u8 ipv4;
	u8 udp_ipv6;
	u8 udp_ipv4;
};

enum sssnic_rss_hash_type {
	SSSNIC_RSS_HASH_ENGINE_TYPE_XOR = 0,
	SSSNIC_RSS_HASH_ENGINE_TYPE_TOEP,
	SSSNIC_RSS_HASH_ENGINE_TYPE_MAX,
};

/* rss */
struct sssnic_rss_indirect_tbl {
	u32 rsvd[4]; /* Make sure that 16B beyond entry[] */
	u16 entry[SSSNIC_RSS_INDIR_SIZE];
};

struct sssnic_rss_context_tbl {
	u32 rsvd[4];
	u32 ctx;
};

#define NIC_CONFIG_ALL_QUEUE_VLAN_CTX 0xFFFF
struct sssnic_vlan_ctx {
	u32 func_id;
	u32 qid; /* if qid = 0xFFFF, config current function all queue */
	u32 vlan_tag;
	u32 vlan_mode;
	u32 vlan_sel;
};

enum sssnic_link_status {
	SSSNIC_LINK_DOWN = 0,
	SSSNIC_LINK_UP
};

struct sssnic_port_info {
	u8 port_type;
	u8 autoneg_cap;
	u8 autoneg_state;
	u8 duplex;
	u8 speed;
	u8 fec;
	u32 supported_mode;
	u32 advertised_mode;
};

struct sssnic_pause_config {
	u8 auto_neg;
	u8 rx_pause;
	u8 tx_pause;
};

#define MODULE_TYPE_SFP 0x3
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D

#define TCAM_IP_TYPE_MASK     0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
#define TCAM_FUNC_ID_MASK     0x7FFF

#define MSG_TO_MGMT_SYNC_RETURN_ERR(err, status, out_size)	\
		((err) || (status) || !(out_size))

struct sssnic_sq_attr {
	u8 dma_attr_off;
	u8 pending_limit;
	u8 coalescing_time;
	u8 intr_en;
	u16 intr_idx;
	u32 l2nic_sqn;
	u64 ci_dma_base;
};

struct vf_data_storage {
	u8 drv_mac_addr[ETH_ALEN];
	u8 user_mac_addr[ETH_ALEN];
	bool registered;
	bool use_specified_mac;
	u16 pf_vlan;
	u8 pf_qos;
	u32 max_rate;
	u32 min_rate;

	bool link_forced;
	bool link_up; /* only valid if VF link is forced */
	bool spoofchk;
	bool trust;
	u16 num_qps;
	u32 support_extra_feature;
};

struct sssnic_port_routine_cmd {
	bool mpu_send_sfp_info;
	bool mpu_send_sfp_abs;

	struct mag_cmd_get_xsfp_info std_sfp_info;
	struct mag_cmd_get_xsfp_present abs;
};

struct sssnic_nic_cfg {
	struct semaphore	cfg_lock;

	/* Valid when pfc is disable */
	bool			pause_set;
	struct sssnic_pause_config	nic_pause;

	u8			pfc_en;
	u8			pfc_bitmap;

	struct sssnic_port_info	port_info;

	/* percentage of pf link bandwidth */
	u32			pf_bw_limit;

	struct sssnic_port_routine_cmd rt_cmd;
	struct mutex sfp_mutex; /* mutex used for copy sfp info */
};

struct sssnic_nic_io {
	void				*hwdev;
	void				*pcidev_hdl;
	void				*dev_hdl;

	u8				link_status;

	struct sssnic_io_queue		*sq;
	struct sssnic_io_queue		*rq;

	u16				num_qps;
	u16				max_qps;

	void				*ci_vaddr_base;
	dma_addr_t			ci_dma_base;

	u8 __iomem			*sqs_db_addr;
	u8 __iomem			*rqs_db_addr;

	u16				max_vfs;
	struct vf_data_storage		*vf_infos;
	struct sssnic_dcb_state		dcb_state;
	struct sssnic_nic_cfg		nic_cfg;

	u16				rx_buff_len;
	u64				feature_cap;
};

struct vf_msg_handler {
	u16 cmd;
	int (*handler)(struct sssnic_nic_io *nic_io, u16 vf,
		       void *buf_in, u16 in_size,
		       void *buf_out, u16 *out_size);
};

struct sssnic_event_handler {
	u16 cmd;
	void (*handler)(void *hwdev, void *buf_in, u16 in_size,
			void *buf_out, u16 *out_size);
};

int sssnic_add_tcam_rule(void *hwdev, struct sssnic_tcam_cfg_rule *tcam_rule);
int sssnic_del_tcam_rule(void *hwdev, u32 index);

int sssnic_alloc_tcam_block(void *hwdev, u16 *index);
int sssnic_free_tcam_block(void *hwdev, u16 *index);

int sssnic_set_fdir_tcam_rule_filter(void *hwdev, bool enable);

int sssnic_flush_tcam_rule(void *hwdev);

/* *
 * @brief sssnic_update_mac - update mac address to hardware
 * @param hwdev: device pointer to hwdev
 * @param old_mac: old mac to delete
 * @param new_mac: new mac to update
 * @param vlan_id: vlan id
 * @param func_id: function index
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
		      u16 func_id);

/* *
 * @brief sssnic_get_default_mac - get default mac address
 * @param hwdev: device pointer to hwdev
 * @param mac_addr: mac address from hardware
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_get_default_mac(void *hwdev, u8 *mac_addr);

/* *
 * @brief sssnic_set_port_mtu - set function mtu
 * @param hwdev: device pointer to hwdev
 * @param new_mtu: mtu
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_port_mtu(void *hwdev, u16 new_mtu);

/* *
 * @brief sssnic_get_link_state - get link state
 * @param hwdev: device pointer to hwdev
 * @param link_state: link state, 0-link down, 1-link up
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_get_link_state(void *hwdev, u8 *link_state);

/* *
 * @brief sssnic_get_vport_stats - get function stats
 * @param hwdev: device pointer to hwdev
 * @param func_id: function index
 * @param stats: function stats
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_get_vport_stats(void *hwdev, u16 func_id, struct sssnic_vport_stats *stats);

/* *
 * @brief sssnic_notify_all_vfs_link_changed - notify to all vfs link changed
 * @param hwdev: device pointer to hwdev
 * @param link_status: link state, 0-link down, 1-link up
 */
void sssnic_notify_all_vfs_link_changed(void *hwdev, u8 link_status);

/* *
 * @brief sssnic_force_drop_tx_pkt - force drop tx packet
 * @param hwdev: device pointer to hwdev
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_force_drop_tx_pkt(void *hwdev);

/* *
 * @brief sssnic_set_rx_mode - set function rx mode
 * @param hwdev: device pointer to hwdev
 * @param enable: rx mode state
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_rx_mode(void *hwdev, u32 enable);

/* *
 * @brief sssnic_set_rx_vlan_offload - set function vlan offload valid state
 * @param hwdev: device pointer to hwdev
 * @param en: 0-disable, 1-enable
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_rx_vlan_offload(void *hwdev, u8 en);

/* *
 * @brief sssnic_set_rx_lro_state - set rx LRO configuration
 * @param hwdev: device pointer to hwdev
 * @param lro_en: 0-disable, 1-enable
 * @param lro_timer: LRO aggregation timeout
 * @param lro_max_pkt_len: LRO coalesce packet size(unit is 1K)
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
			    u32 lro_max_pkt_len);

/* *
 * @brief sssnic_set_vf_spoofchk - set vf spoofchk
 * @param hwdev: device pointer to hwdev
 * @param vf_id:  vf id
 * @param spoofchk: spoofchk
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk);

/* *
 * @brief sssnic_vf_info_spoofchk - get vf spoofchk info
 * @param hwdev: device pointer to hwdev
 * @param vf_id: vf id
 * @retval spoofchk state
 */
bool sssnic_vf_info_spoofchk(void *hwdev, int vf_id);

/* *
 * @brief sssnic_add_vf_vlan - add vf vlan id
 * @param hwdev: device pointer to hwdev
 * @param vf_id: vf id
 * @param vlan: vlan id
 * @param qos: qos
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos);

/* *
 * @brief sssnic_kill_vf_vlan - kill vf vlan
 * @param hwdev: device pointer to hwdev
 * @param vf_id: vf id
 * @param vlan: vlan id
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_kill_vf_vlan(void *hwdev, int vf_id);

/* *
 * @brief sssnic_set_vf_mac - set vf mac
 * @param hwdev: device pointer to hwdev
 * @param vf_id: vf id
 * @param mac_addr: vf mac address
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr);

/* *
 * @brief sssnic_vf_info_vlanprio - get vf vlan priority
 * @param hwdev: device pointer to hwdev
 * @param vf_id: vf id
 * @retval zero: vlan priority
 */
u16 sssnic_vf_info_vlanprio(void *hwdev, int vf_id);

/* *
 * @brief sssnic_set_vf_tx_rate - set vf tx rate
 * @param hwdev: device pointer to hwdev
 * @param vf_id: vf id
 * @param max_rate: max rate
 * @param min_rate: min rate
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate);

/* *
 * @brief sssnic_set_vf_tx_rate - set vf tx rate
 * @param hwdev: device pointer to hwdev
 * @param vf_id: vf id
 * @param ivi: vf info
 * @retval zero: success
 * @retval non-zero: failure
 */
void sssnic_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi);

/* *
 * @brief sssnic_set_vf_link_state - set vf link state
 * @param hwdev: device pointer to hwdev
 * @param vf_id: vf id
 * @param link: link state
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_vf_link_state(void *hwdev, u16 vf_id, int link);

/* *
 * @brief sssnic_get_port_info - set port info
 * @param hwdev: device pointer to hwdev
 * @param port_info: port info
 * @param channel: channel id
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_get_port_info(void *hwdev, struct sssnic_port_info *port_info,
			 u16 channel);

/* *
 * @brief sssnic_set_rss_type - set rss type
 * @param hwdev: device pointer to hwdev
 * @param rss_type: rss type
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_rss_type(void *hwdev, struct sssnic_rss_type rss_type);

/* *
 * @brief sssnic_get_rss_type - get rss type
 * @param hwdev: device pointer to hwdev
 * @param rss_type: rss type
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_get_rss_type(void *hwdev, struct sssnic_rss_type *rss_type);

/* *
 * @brief sssnic_rss_get_hash_engine - get rss hash engine
 * @param hwdev: device pointer to hwdev
 * @param type: hash engine
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_rss_get_hash_engine(void *hwdev, u8 *type);

/* *
 * @brief sssnic_rss_set_hash_engine - set rss hash engine
 * @param hwdev: device pointer to hwdev
 * @param type: hash engine
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_rss_set_hash_engine(void *hwdev, u8 type);

/* *
 * @brief sssnic_rss_cfg - set rss configuration
 * @param hwdev: device pointer to hwdev
 * @param rss_en: enable rss flag
 * @param type: number of TC
 * @param prio_tc: priorityof TC
 * @param num_qps: number of queue
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_rss_cfg(void *hwdev, u8 rss_en, u8 tc_num, u8 *prio_tc,
		   u16 num_qps);

/* *
 * @brief sssnic_rss_set_template_tbl - set template table
 * @param hwdev: device pointer to hwdev
 * @param key: rss key
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_rss_set_hash_key(void *hwdev, const u8 *key);

/* *
 * @brief sssnic_rss_get_template_tbl - get template table
 * @param hwdev: device pointer to hwdev
 * @param key: rss key
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_rss_get_hash_key(void *hwdev, u8 *key);

/* *
 * @brief sssnic_refresh_nic_cfg - refresh port cfg
 * @param hwdev: device pointer to hwdev
 * @param port_info: port information
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_refresh_nic_cfg(void *hwdev, struct sssnic_port_info *port_info);

/* *
 * @brief sssnic_add_vlan - add vlan
 * @param hwdev: device pointer to hwdev
 * @param vlan_id: vlan id
 * @param func_id: function id
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_add_vlan(void *hwdev, u16 vlan_id, u16 func_id);

/* *
 * @brief sssnic_del_vlan - delete vlan
 * @param hwdev: device pointer to hwdev
 * @param vlan_id: vlan id
 * @param func_id: function id
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_del_vlan(void *hwdev, u16 vlan_id, u16 func_id);


/* *
 * @brief sssnic_rss_set_indir_tbl - set rss indirect table
 * @param hwdev: device pointer to hwdev
 * @param indir_table: rss indirect table
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_rss_set_indir_tbl(void *hwdev, const u32 *indir_table);

/* *
 * @brief sssnic_rss_get_indir_tbl - get rss indirect table
 * @param hwdev: device pointer to hwdev
 * @param indir_table: rss indirect table
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_rss_get_indir_tbl(void *hwdev, u32 *indir_table);

/* *
 * @brief sssnic_get_phy_port_stats - get port stats
 * @param hwdev: device pointer to hwdev
 * @param stats: port stats
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats);

int sssnic_get_fpga_phy_port_stats(void *hwdev, struct sssnic_phy_fpga_port_stats *stats);

int sssnic_set_port_funcs_state(void *hwdev, bool enable);

int sssnic_reset_port_link_cfg(void *hwdev);

int sssnic_force_port_relink(void *hwdev);

int sssnic_set_dcb_state(void *hwdev, struct sssnic_dcb_state *dcb_state);

int sssnic_dcb_set_pfc(void *hwdev, u8 pfc_en, u8 pfc_bitmap);

int sssnic_dcb_get_pfc(void *hwdev, u8 *pfc_en_bitmap);

int sssnic_dcb_set_ets(void *hwdev, u8 *cos_tc, u8 *cos_bw, u8 *cos_prio,
		       u8 *tc_bw, u8 *tc_prio);

int sssnic_dcb_set_cos_up_map(void *hwdev, u8 cos_valid_bitmap, u8 *cos_up,
			      u8 max_cos_num);

int sssnic_dcb_set_rq_iq_mapping(void *hwdev, u32 num_rqs, u8 *map,
				 u32 max_map_num);

int sssnic_sync_dcb_state(void *hwdev, u8 op_code, u8 state);

int sssnic_get_pause_info(void *hwdev, struct sssnic_pause_config *nic_pause);

int sssnic_set_pause_info(void *hwdev, struct sssnic_pause_config nic_pause);

int sssnic_set_link_settings(void *hwdev,
			     struct sssnic_link_ksettings *settings);

int sssnic_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);

void sssnic_clear_vfs_info(void *hwdev);

int sssnic_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id);

int sssnic_set_led_status(void *hwdev, enum mag_led_type type,
			  enum mag_led_mode mode);

int sssnic_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en);

int sssnic_set_loopback_mode(void *hwdev, u8 mode, u8 enable);
int sssnic_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable);

#ifdef HAVE_NDO_SET_VF_TRUST
bool sssnic_get_vf_trust(void *hwdev, int vf_id);
int sssnic_set_vf_trust(void *hwdev, u16 vf_id, bool trust);
#endif

int sssnic_set_autoneg(void *hwdev, bool enable);

int sssnic_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int sssnic_get_sfp_eeprom(void *hwdev, u8 *data, u32 len);

bool sssnic_if_sfp_absent(void *hwdev);
int sssnic_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);

/* *
 * @brief sssnic_set_nic_feature_to_hw - sync nic feature to hardware
 * @param hwdev: device pointer to hwdev
 */
int sssnic_set_nic_feature_to_hw(void *hwdev);

/* *
 * @brief sssnic_update_nic_feature - update nic feature
 * @param hwdev: device pointer to hwdev
 * @param s_feature: nic features
 * @param size: @s_feature's array size
 */
void sssnic_update_nic_feature(void *hwdev, u64 s_feature);

/* *
 * @brief sssnic_set_link_status_follow - set link follow status
 * @param hwdev: device pointer to hwdev
 * @param status: link follow status
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_link_status_follow(void *hwdev, enum sssnic_link_follow_status status);

/* *
 * @brief sssnic_update_pf_bw - update pf bandwidth
 * @param hwdev: device pointer to hwdev
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_update_pf_bw(void *hwdev);

/* *
 * @brief sssnic_set_pf_bw_limit - set pf bandwidth limit
 * @param hwdev: device pointer to hwdev
 * @param bw_limit: pf bandwidth limit
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_pf_bw_limit(void *hwdev, u32 bw_limit);

/* *
 * @brief sssnic_set_pf_rate - set pf rate
 * @param hwdev: device pointer to hwdev
 * @param speed_level: speed level
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_pf_rate(void *hwdev, u8 speed_level);


int sssnic_dbg_get_sq_info(void *hwdev, u16 q_id, struct ssshw_nic_sq_info *sq_info,
			   u32 msg_size);

int sssnic_dbg_get_rq_info(void *hwdev, u16 q_id, struct ssshw_nic_rq_info *rq_info,
			   u32 msg_size);

int sssnic_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
			    u8 *wqe, const u16 *wqe_size,
			    enum sssnic_queue_type q_type);


int sssnic_set_ci_table(void *hwdev, struct sssnic_sq_attr *attr);

int l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
			   void *buf_out, u16 *out_size);

int l2nic_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
			      void *buf_out, u16 *out_size, u16 channel);

int sssnic_cfg_vf_vlan(struct sssnic_nic_io *nic_io, u8 opcode, u16 vid,
		       u8 qos, int vf_id);

int sssnic_vf_event_handler(void *hwdev,
			    u16 cmd, void *buf_in, u16 in_size,
			    void *buf_out, u16 *out_size);

void sssnic_pf_event_handler(void *hwdev, u16 cmd,
			     void *buf_in, u16 in_size,
			     void *buf_out, u16 *out_size);

int sssnic_pf_mbox_handler(void *hwdev,
			   u16 vf_id, u16 cmd, void *buf_in, u16 in_size,
			   void *buf_out, u16 *out_size);

u8 sssnic_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data);

int sssnic_vf_func_init(struct sssnic_nic_io *nic_io);

void sssnic_vf_func_free(struct sssnic_nic_io *nic_io);

void sssnic_notify_dcb_state_event(struct sssnic_nic_io *nic_io,
				   struct sssnic_dcb_state *dcb_state);

int sssnic_save_dcb_state(struct sssnic_nic_io *nic_io,
			  struct sssnic_dcb_state *dcb_state);

void sssnic_notify_vf_link_status(struct sssnic_nic_io *nic_io,
				  u16 vf_id, u8 link_status);

int sssnic_vf_mag_event_handler(void *pri_handle, u16 cmd,
				void *buf_in, u16 in_size, void *buf_out,
				u16 *out_size);

void sssnic_pf_mag_event_handler(void *pri_handle, u16 cmd,
				 void *buf_in, u16 in_size, void *buf_out,
				 u16 *out_size);

int sssnic_pf_mag_mbox_handler(void *pri_handle, u16 vf_id,
			       u16 cmd, void *buf_in, u16 in_size,
			       void *buf_out, u16 *out_size);


/* *
 * @brief sssnic_set_mac - set mac address
 * @param hwdev: device pointer to hwdev
 * @param mac_addr: mac address from hardware
 * @param vlan_id: vlan id
 * @param func_id: function index
 * @param channel: channel id
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id, u16 channel);

/* *
 * @brief sssnic_del_mac - delete mac address
 * @param hwdev: device pointer to hwdev
 * @param mac_addr: mac address from hardware
 * @param vlan_id: vlan id
 * @param func_id: function index
 * @param channel: channel id
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id, u16 channel);

/* *
 * @brief sssnic_set_vport_enable - set function valid status
 * @param hwdev: device pointer to hwdev
 * @param func_id: global function index
 * @param enable: 0-disable, 1-enable
 * @param channel: channel id
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_vport_enable(void *hwdev, u16 func_id, bool enable, u16 channel);

/* *
 * @brief sssnic_set_port_enable - set port status
 * @param hwdev: device pointer to hwdev
 * @param enable: 0-disable, 1-enable
 * @param channel: channel id
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_set_port_enable(void *hwdev, bool enable, u16 channel);

/* *
 * @brief sssnic_flush_qps_res - flush queue pairs resource in hardware
 * @param hwdev: device pointer to hwdev
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_flush_qps_res(void *hwdev);

/* *
 * @brief sssnic_init_nic_hwdev - init nic hwdev
 * @param hwdev: device pointer to hwdev
 * @param pcidev_hdl: pointer to pcidev or handler
 * @param dev_hdl: pointer to pcidev->dev or handler, for sdk_err() or
 * dma_alloc()
 * @param rx_buff_len: rx_buff_len is receive buffer length
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl, u16 rx_buff_len);

/* *
 * @brief sssnic_free_nic_hwdev - free nic hwdev
 * @param hwdev: device pointer to hwdev
 * @retval zero: success
 * @retval non-zero: failure
 */
void sssnic_free_nic_hwdev(void *hwdev);

/* *
 * @brief sssnic_get_speed - set link speed
 * @param hwdev: device pointer to hwdev
 * @param port_info: link speed
 * @param channel: channel id
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_get_speed(void *hwdev, enum mag_cmd_port_speed *speed, u16 channel);

int sssnic_get_dcb_state(void *hwdev, struct sssnic_dcb_state *dcb_state);

int sssnic_get_pf_dcb_state(void *hwdev, struct sssnic_dcb_state *dcb_state);

int sssnic_get_cos_by_pri(void *hwdev, u8 pri, u8 *cos);

/* *
 * @brief sssnic_create_qps - create queue pairs
 * @param hwdev: device pointer to hwdev
 * @param num_qp: number of queue pairs
 * @param sq_depth: sq depth
 * @param rq_depth: rq depth
 * @param qps_msix_arry: msix info
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_create_qps(void *hwdev, u16 num_qp, u32 sq_depth, u32 rq_depth,
		      struct ssshw_irq_info *qps_msix_arry);

/* *
 * @brief sssnic_destroy_qps - destroy queue pairs
 * @param hwdev: device pointer to hwdev
 */
void sssnic_destroy_qps(void *hwdev);

/* *
 * @brief sssnic_get_nic_queue - get nic queue
 * @param hwdev: device pointer to hwdev
 * @param q_id: queue index
 * @param q_type: queue type
 * @retval queue address
 */
void *sssnic_get_nic_queue(void *hwdev, u16 q_id, enum sssnic_queue_type q_type);

/* *
 * @brief sssnic_init_qp_ctxts - init queue pair context
 * @param hwdev: device pointer to hwdev
 * @retval zero: success
 * @retval non-zero: failure
 */
int sssnic_init_qp_ctxts(void *hwdev);

/* *
 * @brief sssnic_free_qp_ctxts - free queue pairs
 * @param hwdev: device pointer to hwdev
 */
void sssnic_free_qp_ctxts(void *hwdev);


#endif
